#include <osg/Geode>
#include <osg/Geometry>
#include <osg/NodeVisitor>
#include <osg/ShapeDrawable>
#include <osg/Group>
#include <osg/PolygonMode>
#include <osgViewer/Viewer>
#include <osg/Notify>
#include <iostream>
#include <osg/DisplaySettings>
#include <osg/Material>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osg/PolygonMode>
#include <cstdlib>


class ColorSetter : public osg::NodeVisitor
{
public:
    ColorSetter(const osg::Vec4& color) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _color(color) {}

    virtual void apply(osg::Node& node)
    {
        osg::StateSet* stateSet = node.getOrCreateStateSet();
        osg::ref_ptr<osg::Material> material = new osg::Material;
        // 禁用颜色追踪, 这样颜色就会直接使用设置的颜色
        //material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
        material->setAmbient(osg::Material::FRONT_AND_BACK, _color);
        material->setDiffuse(osg::Material::FRONT_AND_BACK, _color);
        material->setShininess(osg::Material::FRONT_AND_BACK, 0.0f);
        //material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
        osg::ref_ptr<osg::PolygonMode> polygonMode = new osg::PolygonMode;
        polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
        stateSet->setAttributeAndModes(polygonMode, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
        stateSet->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
        //stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

        traverse(node);
    }

private:
    osg::Vec4 _color;
};
//class ColorSetter : public osg::NodeVisitor
//{
//public:
//    ColorSetter(const osg::Vec4& color) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _color(color) {}
//
//    virtual void apply(osg::Node& node)
//    {
//        osg::StateSet* stateSet = node.getOrCreateStateSet();
//
//        // 强制禁用所有可能影响颜色的特性
//        stateSet->setMode(GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
//        stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
//        stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
//
//        // 设置颜色
//        stateSet->setAttributeAndModes(new osg::Material, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
//        stateSet->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL),
//            osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
//
//        // 使用固定颜色
//        stateSet->addUniform(new osg::Uniform("osg_Color", _color));
//
//        traverse(node);
//    }
//
//private:
//    osg::Vec4 _color;
//};
/**
    加载模型，需要设置插件的库路径，否则会报错
    系统变量中设置osg插件的库路径：D:\soft\vcpkg\installed\x64-windows\plugins\osgPlugins-3.6.5
*/
int main(int argc, char **argv)
{
        // 启用调试输出
    osg::setNotifyLevel(osg::DEBUG_INFO);
    osg::DisplaySettings::instance()->setNumMultiSamples(4);
    osg::DisplaySettings::instance()->setMinimumNumStencilBits(8);
    osgViewer::Viewer viewer;
    // 在创建viewer后添加
    viewer.setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
    // 或者
    //viewer.setThreadingModel(osgViewer::ViewerBase::CullDrawThreadPerContext);
    auto root = osgDB::readNodeFile("D:/learn/osg-learning/cow.osgt");

    //osg::ref_ptr<osg::Material> material = new osg::Material;
    //material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
    //material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 0.0, 0.0, 1.0));
    //material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 0.0, 0.0, 1.0));
    ////material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1.0, 1.0, 1.0));
    //osg::ref_ptr<osg::StateSet> stateSet = root->getOrCreateStateSet();
    //// 应用材质并禁用纹理
    //stateSet->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
    //stateSet->setMode(GL_TEXTURE_2D, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF);
    //stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

    // 在StateSet中添加uniform颜色
    //osg::ref_ptr<osg::StateSet> stateSet = root->getOrCreateStateSet();
    //stateSet->addUniform(new osg::Uniform("overrideColor", osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)));
    //stateSet->setDefine("USE_OVERRIDE_COLOR");

    // 更简单的方式，直接设置颜色
    //osg::ref_ptr<osg::StateSet> stateSet = root->getOrCreateStateSet();
    //osg::ref_ptr<osg::Material> material = new osg::Material;
    //material->setColorMode(osg::Material::OFF); // 关闭颜色模式
    //material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    //stateSet->setAttribute(material);

        // 创建并设置红色材质
    //osg::ref_ptr<osg::Material> material = new osg::Material;
    //material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
    //material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    //material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    //material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    //material->setShininess(osg::Material::FRONT_AND_BACK, 0.0f);

    //// 获取或创建StateSet并应用材质
    //osg::ref_ptr<osg::StateSet> stateSet = root->getOrCreateStateSet();
    //stateSet->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
    //stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
    ColorSetter colorSetter(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    root->accept(colorSetter); 

    //下面是正常的方案
    //osg::ref_ptr<osg::Material> mat = new osg::Material;
    //mat->setName("RedCow");
    //osg::Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
    //mat->setAmbient(osg::Material::FRONT_AND_BACK, red);
    //mat->setDiffuse(osg::Material::FRONT_AND_BACK, red);
    //mat->setColorMode(osg::Material::OFF);   // 关键：禁用 color tracking

    //// 3. 把材质挂到 StateSet，并强制生效
    //root->getOrCreateStateSet()->setAttributeAndModes(
    //    mat.get(),
    //    osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE
    //);

    viewer.setSceneData(root);
    try {
        auto parents =  root->getParents();
        return viewer.run();
    } catch (const std::exception& e) {
        std::cerr << "Exception caught: " << e.what() << std::endl;
        return -1;
    }
}